﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Assets.Scripts.Net.Data;
using Assets.Scripts.Tool;
using Assets.Scripts.UI;
using MiniJSON;
using Newtonsoft.Json;
using UnityEngine;

namespace Assets.Scripts.Net
{
    /// <summary>
    ///     请求的类型
    /// </summary>
    public enum RequestType
    {
        Login, //登入
        ChangePassword,//修改密码
        HomeWork,//家庭作业
        MockExam,//模拟考试
        QuestionList,//问题列表 
        EnterExamination,//进入考试
        ExamquestList,//获取考试题目
        DoExam,//开始考试，todo......
        GetScore,//查看成绩
        ErrorList,//错题本
        RemoveError,//移除错题本中的某道题目
        ClearErrorList,//清空某一类作业的所有错题
        SendTestPaper,//发送考试试卷,随机之后的试卷
        SubmitPaper,//发送考试结果,同时更新之前的试卷信息
        GetPaperInfo,//得到试卷信息  
        SubmitPersonInfo,//提交个人信息
    }

    public class NetConfig
    {
        public static string URL_HOST = "http://192.168.0.225:8080/";
        public static string URL_RESHOST = "http://192.168.0.225:8080/";//资源的ip地址  
        public readonly static string NET_RES_PATH = "C:/IAClient/Data/NetResources";//下载资源的存放路径
        public readonly static string NET_RES_CONFIG_PATH = "C:/IAClient/Data/NetResources/NetResConfig.bytes";//下载资源的配置文件路径
    }

    public class NetManager : SingleMono<NetManager>
    {

        public Dictionary<RequestType,string>requestDict=new Dictionary<RequestType,string>();
        public string sessionId = ""; //存储sessionId

        //初始化
        private void Awake()
        {           
            //初始化资源路径
            DirectoryInfo directory = new DirectoryInfo(NetConfig.NET_RES_PATH);
            if(!directory.Exists)
                directory.Create();
        }

        /// <summary>
        /// 发送请求
        /// 修改把重复请求过滤掉
        /// </summary>
        /// <param name="type">请求类型</param>
        /// <param name="successResponse">成功返回消息之后的回调</param>
        /// <param name="failedResponse">失败后的回调</param>
        public void SendRequest(RequestType type, Dictionary<string, object> dict, Action successResponse, Action<string> failedResponse = null)
        {
            if (requestDict.ContainsKey(type))
            {
#if !TEST
                ExitLoop();
                return;
#endif
            }
#if !TEST
            requestDict.Add(type, "");
#endif
            NetReaderFactory.Instance().NetResUrls.Clear();
            string url = NetConfig.URL_HOST;
            url += type.ToString().ToLower();          
            SignDict(dict);//在字典中添加签名
            StartCoroutine(Post(type,url, dict, successResponse,failedResponse));
        }

        /// <summary>
        ///    返回一个普通基础Dict
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, object> GetDict()   
        {
            Dictionary<string, object> dict=new Dictionary<string, object>();
            dict.Add("sessionid",sessionId);
            return dict;
        }

        /// <summary>
        ///     Post请求
        /// </summary>
        /// <returns></returns>
        private IEnumerator Post(RequestType type,string url, Dictionary<string, object> dict, Action successResponse, Action<string> failedResponse = null)
        {
            string temp = url;
            if (dict.ContainsKey("sessionid"))
            {
                string sessionid =(string)dict["sessionid"];           
                temp += ";jsessionid=" + sessionid;
            }
            var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore};
            string json = JsonConvert.SerializeObject(dict, Formatting.None, jSetting);//过滤空值
            Encoding encoding = new UTF8Encoding();
            Debug.Log("请求的URl地址是:"+temp);
            Debug.Log("发送的信息是:"+json);
            using (var www = new WWW(temp,encoding.GetBytes(json)))
            {               
                yield return www;
                if (www.isDone && www.error == null)
                {                   
                    if (string.IsNullOrEmpty(www.text)) yield break;
                    Debug.Log("返回的信息是：" + www.text);
                    var dictionary = Json.Deserialize(www.text) as Dictionary<string, object>;  
                    if (dictionary != null && dictionary.ContainsKey("res"))
                    {
                        switch (dictionary["res"].ToString())
                        {
                            case "0": //失败
                                if (dictionary.ContainsKey("method"))
                                {
                                    switch (dictionary["method"].ToString())
                                    {
                                        case "login"://登入
                                            UIManager._Instance.ShowTipInfo("登入失败");
                                            break;
                                        case "doexam"://进入考试                                           
                                            break;
                                    }
                                }
                                //失败的回调函数
                                if (failedResponse != null) failedResponse("1000");
                                break;
                            case "1": //参数错误
                                UIManager._Instance.ShowTipInfo("参数错误");
                                if (failedResponse != null) failedResponse(null);
                                break;
                            case "2": //成功 
                                if (dictionary.ContainsKey("sessionid"))
                                {
                                    sessionId = dictionary["sessionid"].ToString();
                                    dictionary.Remove("sessionid");
                                }
                                if (dictionary.ContainsKey("method"))
                                {
                                    switch (dictionary["method"].ToString())
                                    {
                                        case "login": //登入方法
                                            NetReaderFactory.Instance()
                                                .ReaderInfo(ReaderInfoType.StudentInfo, dictionary);
                                            break;
                                        case "enterexamination":
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.ExamInfo, dictionary);
                                            break;
                                        case "mockexam":
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.CourseInfo, null,dictionary["coursedata"] as List<object>);
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.PaperInfo, null,dictionary["paperdata"]as List<object>);
                                            break;
                                        case "questionlist":
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.QueInfo, null, dictionary["quedata"] as List<object>);
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.AnsInfo, null, dictionary["ansdata"] as List<object>);
                                            break;
                                        case "homework":
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.CourseInfo, null,dictionary["coursedata"] as List<object>);
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.HomeworkInfo, null,dictionary["homeworkdata"]as List<object>);
                                            break;
                                        case "getpaperinfo":
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.QueInfo, null, dictionary["quedata"] as List<object>);
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.AnsInfo, null, dictionary["ansdata"] as List<object>);
                                            break;
                                        case "errorlist":
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.CourseInfo, null, dictionary["coursedata"] as List<object>);
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.QueInfo, null, dictionary["quedata"] as List<object>);
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.AnsInfo, null, dictionary["ansdata"] as List<object>);
                                            break;
                                        case "getscore":
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.CourseInfo, null, dictionary["coursedata"] as List<object>);
                                            NetReaderFactory.Instance().ReaderInfo(ReaderInfoType.PaperInfo, null, dictionary["paperdata"] as List<object>);
                                            break;
                                    }
                                }
                                if (successResponse != null) successResponse();
                                break;
                            case "3": //签名错误MD5
                                if (failedResponse != null) failedResponse("签名错误");
                                break;
                            case "4": 
                                if (dictionary.ContainsKey("method"))
                                {
                                    switch (dictionary["method"].ToString())
                                    {
                                        case "login": //用户名、密码错误    
                                            UIManager._Instance.ShowTipInfo("用户密码错误");
                                            break;
                                        case "doexam":
                                            UIManager._Instance.LoginOutDateOnDoExam();
                                            break;
                                        default://登入过期
                                            UIManager._Instance.LoginOutDate();
                                            break;
                                    }
                                }
                                break;
                            case "5": 
                                if (dictionary.ContainsKey("method"))
                                {
                                    switch (dictionary["method"].ToString())
                                    {
                                        case "enterexamination": //没有考试
                                            UIManager._Instance.ShowTipInfo("无考试");
                                            break;
                                        default://登入过期
                                            UIManager._Instance.LoginOutDate();
                                            break;
                                    }
                                }
                                break;
                            case "8":
                                //用户异地登入
                                UIManager._Instance.OtherUserLogin();
                                break;
                        }
                    }
                    requestDict.Remove(type);
                }
                else
                {
                    requestDict.Remove(type);
                    ExitLoop();
                    if (failedResponse != null)
                    {
                        if (www.responseHeaders.ContainsKey("MSG") && www.responseHeaders["MSG"] == "1004")
                        {
                            failedResponse("1004");
                        }
                        else
                        {
                            failedResponse(null);
                        }
                    }
                    else 
                    {
                        if(www.responseHeaders.ContainsKey("MSG") && www.responseHeaders["MSG"] == "1004")
                        {
                            //用户异地登入 
                            UIManager._Instance.OtherUserLogin();
                        }
                    }
                }
            }
        }

        void ExitLoop()
        {
            UIManager._Instance.ExitPanel("LoadingPanel(Clone)");
            UIManager._Instance.ExitPanel("LoadingLoopPanel(Clone)");
        }

        /// <summary>
        /// 在字典中注册签名
        /// </summary>
        /// <param name="dict"></param>
        void SignDict(Dictionary<string, object> dict)
        {
            if(dict.ContainsKey("sign"))return;
            SortedDictionary<string, object> sortedDict = new SortedDictionary<string, object>();
            foreach (KeyValuePair<string, object> item in dict)
            {
                sortedDict.Add(item.Key, item.Value);
            }
            string unsignStr = "";
            int index = 0;
            foreach (KeyValuePair<string, object> item in sortedDict)
            {
                if (index != 0)
                    unsignStr += "&";
                //Debug.Log("item:"+item);
                string type = item.Value.GetType().ToString();//bug null
                //Debug.Log("Type:"+type);
                unsignStr += item.Key + "=" + item.Value;                    
                index++;
            }
            string signStr = Md5Encript.GetMd5HashStr(unsignStr);
            Debug.Log("unsignStr:"+unsignStr);
            Debug.Log("签名md5:" + signStr);
            dict.Add("sign", signStr);
        }
    }
}